from datetime import datetime
from typing import List, Optional

class Customer:
    def __init__(self, name: str, contact: str, delivery_address: str, active: bool):
        self.name = name
        self.contact = contact
        self.delivery_address = delivery_address
        self.active = active
        self.orders: List['Order'] = []

    def add_order(self, order: 'Order'):
        self.orders.append(order)

class Order:
    def __init__(self, create_date: datetime, status: str):
        self.create_date = create_date
        self.status = status
        self.details: List['OrderDetail'] = []
        self.payment: Optional['Payment'] = None

    def add_detail(self, detail: 'OrderDetail'):
        self.details.append(detail)

    def set_payment(self, payment: 'Payment'):
        self.payment = payment

class OrderDetail:
    def __init__(self, quantity: int, product: 'Product'):
        self.quantity = quantity
        self.product = product

    def calculate_subtotal(self) -> float:
        return self.quantity * self.product.get_price_for_quantity(self.quantity)

    def calculate_weight(self) -> float:
        return self.quantity * self.product.get_weight()

class Product:
    def __init__(self, title: str, weight: float, description: str, price: float):
        self.title = title
        self.weight = weight
        self.description = description
        self.price = price

    def get_price_for_quantity(self, quantity: int) -> float:
        return self.price * quantity

    def get_weight(self) -> float:
        return self.weight

class Payment:
    def __init__(self, amount: float):
        self.amount = amount

class Credit(Payment):
    def __init__(self, number: str, card_type: str, expire_date: datetime, amount: float):
        super().__init__(amount)
        self.number = number
        self.card_type = card_type
        self.expire_date = expire_date

class Cash(Payment):
    def __init__(self, cash_Tendered: float):
        super().__init__(cash_Tendered)

class WireTransfer(Payment):
    def __init__(self, bank_id: str, bank_name: str, amount: float):
        super().__init__(amount)
        self.bank_id = bank_id
        self.bank_name = bank_name

class AliPay(Payment):
    def __init__(self, number: str, amount: float):
        super().__init__(amount)
        self.number = number

class WeixinPay(Payment):
    def __init__(self, number: str, amount: float):
        super().__init__(amount)
        self.number = number

# 示例
if __name__ == "__main__":
    # 创建客户
    customer = Customer("xxs", "1433223", "CTGU", True)
    
    # 创建产品
    product1 = Product("Apple", 2.5, "Big laptop", 1000.00)
    product2 = Product("Mouse", 0.1, "Wireless mouse", 50.00)
    
    # 创建订单
    order = Order(datetime.now(), "CREATE")
    
    # 添加订单详情
    detail1 = OrderDetail(1, product1)
    detail2 = OrderDetail(2, product2)
    
    order.add_detail(detail1)
    order.add_detail(detail2)
    
    # 设置支付方式
    payment = Credit("1234-5678-9876-5432", "ABC", datetime(2025, 12, 31), 1100.00)
    order.set_payment(payment)
    
    # 添加订单到客户
    customer.add_order(order)

    # 打印订单主要信息
    print(f"客户姓名(Customer name): {customer.name}")
    print(f"联系电话(contact): {customer.contact}")
    print(f"邮寄地址(deliveryAddress): {customer.delivery_address}")
    print(f"订单状态(Order Status): {order.status}")
    print(f"创建日期(Order Creation Date): {order.create_date}")

    print("\n订单详情(Order Details):")
    for detail in order.details:
        subtotal = detail.calculate_subtotal()
        print(f"- 商品名称(Product title): {detail.product.title}, 数量(Quantity): {detail.quantity}, 小计(Subtotal): {subtotal:.2f}, 重量(Weight): {detail.calculate_weight():.2f}")

    if order.payment:
        print(f"\n支付方式(Payment): {type(order.payment).__name__}")
        print(f"支付金额(Payment Amount): {order.payment.amount:.2f}")
        if isinstance(order.payment, Credit):
            print(f"银行卡号(Card Number): {order.payment.number}, 银行类型(Card Type): {order.payment.card_type}, 过期日期(Expiry Date): {order.payment.expire_date.strftime('%Y-%m-%d')}")
